<html>
<head><meta charset="utf-8"><title>Why lazy parsing won&#x27;t work for rust-analyzer · t-compiler/rust-analyzer · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/index.html">t-compiler/rust-analyzer</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html">Why lazy parsing won&#x27;t work for rust-analyzer</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="163448767"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163448767" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163448767">(Apr 16 2019 at 07:58)</a>:</h4>
<p>I've been reading <a href="https://v8.dev/blog/preparser" target="_blank" title="https://v8.dev/blog/preparser">https://v8.dev/blog/preparser</a> which mentions a useful trick for speedy parsing: not parsing function bodies at all.</p>
<p>It's a shame that we can't do this in Rust, because impls inside function bodies are globally visible. See <a href="https://github.com/rust-analyzer/rust-analyzer/issues/1152" target="_blank" title="https://github.com/rust-analyzer/rust-analyzer/issues/1152">https://github.com/rust-analyzer/rust-analyzer/issues/1152</a> for details.</p>
<p>I wonder if we can deprecate local impls for global types in the next edition. Alternatively, maybe I am missing a simple heuristic for determining if the function has to be parsed lazily?</p>



<a name="163449005"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163449005" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> detrumi <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163449005">(Apr 16 2019 at 08:03)</a>:</h4>
<p>It's very unintuitive that nested impls are visible globally. But maybe it's problematic for the compiler to track impls at multiple levels?</p>



<a name="163449324"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163449324" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163449324">(Apr 16 2019 at 08:08)</a>:</h4>
<p>its definitely easier to just track impls globally, per crate, but it doesn't have that much harder to add some restrictions a-la coherence here</p>



<a name="163451559"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163451559" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163451559">(Apr 16 2019 at 08:50)</a>:</h4>
<p>I agree that it's not useful at all to allow local impls for global types. But i think it's ok to skip function bodies that have neither <code>impl</code> keyword nor macro invocation items in it?</p>



<a name="163451681"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163451681" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163451681">(Apr 16 2019 at 08:52)</a>:</h4>
<p>Hm, that indeed looks like a heuristic I've overlooked!</p>
<p>I wonder which proportion of functions invoke macros though...</p>



<a name="163451792"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163451792" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163451792">(Apr 16 2019 at 08:54)</a>:</h4>
<p>treat any ! that doesn't look like a unary ! or never type as maybe  a macro?  The guess doesn't have to be accurate at all.</p>



<a name="163452434"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163452434" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Vadim Petrochenkov <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163452434">(Apr 16 2019 at 09:05)</a>:</h4>
<p>cc <a href="https://github.com/rust-lang/rfcs/issues/1355" target="_blank" title="https://github.com/rust-lang/rfcs/issues/1355">https://github.com/rust-lang/rfcs/issues/1355</a></p>



<a name="163461024"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163461024" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163461024">(Apr 16 2019 at 11:38)</a>:</h4>
<p>I assume this can't be prohibited backwards-compatibly, but if the compiler emitted a warning in such cases we could maybe just assume no one does it and go ahead with lazy parsing?</p>



<a name="163461154"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163461154" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163461154">(Apr 16 2019 at 11:40)</a>:</h4>
<p>Yeah, that's my plan: emit deprecation warning, proceed with lazy parsing. Maaaaybe switch to deny by default warning after crater and some time.  So perhaps I've closed the issue on rust-analyzer prematurely? Lazy parsing should save <strong>a ton</strong> of memory</p>



<a name="163461171"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163461171" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163461171">(Apr 16 2019 at 11:41)</a>:</h4>
<p>and we sort-of have all the necessary infra for it already, for incremental block reparsign</p>



<a name="163461187"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163461187" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163461187">(Apr 16 2019 at 11:41)</a>:</h4>
<p>this means though that I need to re-do rowan's API once again :D</p>



<a name="163463117"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163463117" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> weiznich <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163463117">(Apr 16 2019 at 12:11)</a>:</h4>
<p>So to just add a point to no one implements traits inside of functions: We are doing this in <a href="https://github.com/diesel-rs/diesel/blob/master/diesel_derives/src/util.rs#L10" target="_blank" title="https://github.com/diesel-rs/diesel/blob/master/diesel_derives/src/util.rs#L10">diesel_derives</a> as part of our code gen. We use functions to provide a new scope to don't pollute the outer namespace with imported/generated items. We've used mods at some point of time, but that was already disallowed (Or better, that only worked because of an bug that allowed to accessing items from the parent scope in proc macro generated modules.)</p>



<a name="163463934"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163463934" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163463934">(Apr 16 2019 at 12:24)</a>:</h4>
<p>why can't that be <code>fn #mod_name { use super::*;  use diesel; use std; }</code> ?</p>



<a name="163467012"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163467012" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> weiznich <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163467012">(Apr 16 2019 at 13:06)</a>:</h4>
<p>You mean <code>mod #mod_name { use super::*; …}</code>?</p>



<a name="163467076"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163467076" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> weiznich <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163467076">(Apr 16 2019 at 13:07)</a>:</h4>
<p>Because <code>use super::*</code> does not import things that are imported into the parent scope. (At least it worked that way when we switched to using functions there.)</p>



<a name="163467437"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163467437" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163467437">(Apr 16 2019 at 13:11)</a>:</h4>
<p><span class="user-mention" data-user-id="215423">@weiznich</span> <code>use super::*</code> does import (privatly) used stuff from the parent scope now!</p>



<a name="163467520"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163467520" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163467520">(Apr 16 2019 at 13:12)</a>:</h4>
<p>But yeah, this example is convincing enough that deny_by_default is not going to happen in the foreseeable future, thanks!</p>



<a name="163468201"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Why%20lazy%20parsing%20won%27t%20work%20for%20rust-analyzer/near/163468201" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> weiznich <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Why.20lazy.20parsing.20won&#x27;t.20work.20for.20rust-analyzer.html#163468201">(Apr 16 2019 at 13:20)</a>:</h4>
<p>Oh, good to know that <code>use super::*</code> now also imports the privately imported stuff. That wouldn't make it to hard for us to change it back <span aria-label="wink" class="emoji emoji-1f609" role="img" title="wink">:wink:</span></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>